package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.service.TestService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @author: atguigu
 * @create: 2024-12-04 14:04
 */
@Slf4j
@Service
public class TestServiceImpl implements TestService {
    @Override
    @Cacheable(value = "testCache", key = "#id")
    public String getData(Long id) {
        log.info("[缓存测试]查询数据库...{}", id);
        return "data:" + id;
    }


    @Override
    @CacheEvict(value = "testCache", key = "#id")
    public void updateData(Long id) {
        log.info("[缓存测试]更新数据库...{}", id);
    }


    @Autowired
    private RedissonClient redisson;


    /**
     * 读取数据，先获取到记录的读锁，执行读业务，释放读锁
     *
     * @param id
     * @return
     */
    @Override
    public String read(Long id) {
        //1.获取到读写锁对象
        RReadWriteLock rwlock = redisson.getReadWriteLock("myLock:" + id);
        //2.获取读锁对象 获取读锁
        RLock lock = rwlock.readLock();
        // 获取读锁成功期间 ，禁止并发写操作   允许并发读
        lock.lock(5, TimeUnit.SECONDS);
        try {
            log.info("获取到读锁执行业务....");
            return "val:" + id;
        } finally {
            //3.释放读锁  TODO等待5s自动自动释放
        }
    }

    /**
     * 写入数据，先获取到记录的写锁，执行写业务，释放写锁
     *
     * @param id
     */
    @Override
    public void write(Long id) {
        //1.获取到读写锁对象
        RReadWriteLock rwlock = redisson.getReadWriteLock("myLock:" + id);
        //2.获取写锁对象 获取写锁
        RLock lock = rwlock.writeLock();
        // 获取写锁成功期间 ，禁止并发写操作
        lock.lock(5, TimeUnit.SECONDS);
        try {
            log.info("获取到写锁执行业务");
        } finally {
            //3.释放写锁 TODO 等待5s自动自动释放
        }

    }
}
